package com.restkeeper.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class ShowdocCodeUtils {
 public static final String ALGORITHM = "AES";
 public static final String SECRET_AES_ECB_MODE = "ECB";
 public static final String SECRET_AES_PKCS5_PADDING = "PKCS5Padding";

 /**
  * 解密
  *
  * <p>
  * byte[] -> byte[]
  *
  * @param mode       模式
  * @param padding    填充
  * @param key        密钥
  * @param iv         向量，如果模式不用向量，可传递null
  * @param ciphertext 密文
  * @return 明文
  */
 public static byte[] decrypt(String mode, String padding, byte[] key, byte[] iv, byte[] ciphertext) {
  return doBytes(mode, padding, key, iv, ciphertext, Cipher.DECRYPT_MODE);
 }

 private static byte[] doBytes(String mode, String padding, byte[] key, byte[] iv, byte[] input, int opMode) {
  Cipher cipher = createCipher(mode, padding, key, iv, opMode);
  try {
   byte[] output = cipher.doFinal(input);
   return output;
  } catch (IllegalBlockSizeException | BadPaddingException e) {
   throw new RuntimeException(e);
  }
 }

 private static Cipher createCipher(String mode, String padding, byte[] key, byte[] iv, int opMode) {
  SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
  IvParameterSpec ivSpec = null;
  if (iv != null) {
   ivSpec = new IvParameterSpec(iv);
  }

  String transformation = ALGORITHM + "/" + mode + "/" + padding;
  Cipher cipher;
  try {
   cipher = Cipher.getInstance(transformation);
   cipher.init(opMode, keySpec, ivSpec);
   return cipher;
  } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
    | InvalidAlgorithmParameterException e) {
   throw new RuntimeException(e);
  }
 }

}
